package com.project.oauth2Server.Authorization;

import com.project.annotation.model.UserConfig;
import com.project.oauth2Server.config.AuthConfig;
import com.project.oauth2Server.config.redis.UserInfoRedis;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;

@Controller
public class UserAuthServer implements UserDetailsService {

    @Autowired
    UserInfoRedis userInfoRedis;

    @Autowired
    AuthConfig authConfig;

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        UserConfig userInfo = configUser(s);

        if (null == userInfo){
            userInfo = userInfoRedis.getExecutor().getHashMapObject(s, UserConfig.class);
        }

        if (null == userInfo){
            return null;
        }

        return User
                .withUsername(userInfo.getUserName())
                .password(userInfo.getPassword())
                .roles(userInfo.getRoles())
                .accountExpired(userInfo.isAccountNonExpired())
                .accountLocked(userInfo.isAccountNonLocked())
                .credentialsExpired(userInfo.isCredentialsNonExpired())
                .disabled(userInfo.isEnabled()).passwordEncoder((psw) -> new BCryptPasswordEncoder().encode(psw)).build();
    }

    private UserConfig configUser(String s) {
        UserConfig userInfo = userInfoRedis.getExecutor().getHashMapObject(s, UserConfig.class);
        try{
            if (null == userInfo) {
                for (UserConfig uc : authConfig.getUsers()){
                    if (uc.getUserName().equals(s)){
                        userInfoRedis.getExecutor().addMap(s, uc);
                        return uc;
                    }
                }
            }
        } catch (Exception e){
            e.printStackTrace();
        }

        return userInfo;
    }
}
